home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Information
/
CSMP Digest
/
volume 3
/
csmp-digest-v3-084
< prev
next >
Wrap
Text File
|
1995-12-31
|
41KB
|
1,168 lines
C.S.M.P. Digest Thu, 16 Feb 95 Volume 3 : Issue 84
Today's Topics:
A portable random generator
Dlog code snippet request
FindWorkBreaks quirky?
Looking for Get-Put URL AE suite info
Random() replacement anyone?
UnloadSeg - unloading code segments
Where to send applications I've written?
The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
(pottier@clipper.ens.fr).
The digest is a collection of article threads from the internet newsgroup
comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
regularly and want an archive of the discussions. If you don't know what a
newsgroup is, you probably don't have access to it. Ask your systems
administrator(s) for details. If you don't have access to news, you may
still be able to post messages to the group by using a mail server like
anon.penet.fi (mail help@anon.penet.fi for more information).
Each issue of the digest contains one or more sets of articles (called
threads), with each set corresponding to a 'discussion' of a particular
subject. The articles are not edited; all articles included in this digest
are in their original posted form (as received by our news server at
nef.ens.fr). Article threads are not added to the digest until the last
article added to the thread is at least two weeks old (this is to ensure that
the thread is dead before adding it to the digest). Article threads that
consist of only one message are generally not included in the digest.
The digest is officially distributed by two means, by email and ftp.
If you want to receive the digest by mail, send email to listserv@ens.fr
with no subject and one of the following commands as body:
help Sends you a summary of commands
subscribe csmp-digest Your Name Adds you to the mailing list
signoff csmp-digest Removes you from the list
Once you have subscribed, you will automatically receive each new
issue as it is created.
The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
Questions related to the ftp site should be directed to
scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
digest are available there.
Also, the digests are available to WAIS users. To search back issues
with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
-------------------------------------------------------
>From vecoven@montefiore.ulg.ac.be (Frederic Vecoven)
Subject: A portable random generator
Date: Wed, 1 Feb 1995 09:22:52 +0100
Organization: Universiti de Lihge
After reading lots of message about random numbers, I post
this generator for those interested. It's quite good (the pseudo-
period is very high) and portable.
#define M1 259200
#define IA1 7141
#define IC1 54773
#define RM1 (1.0 / M1)
#define M2 134456
#define IC2 28411
#define RM2 (1.0 / M2)
#define M3 243000
#define IA3 4561
#define IC3 51349
/* initialize the pseudo-sequence with a integer <= 0 */
double ran1(idum)
int *idum;
{
static long ix1,ix2,ix3;
static int iff = 0;
static double r[98];
double temp;
int j;
if (*idum < 0 || iff == 0) {
iff = 1;
ix1 = (IC1 - (*idum)) % M1;
ix1 = (IA1 * ix1 + IC1) % M1;
ix2 = ix1 % M2;
ix1 = (IA1 * ix1 + IC1) % M1;
ix3 = ix1 % M3;
for (j=1;j<97;j++) {
ix1 = (IA1 * ix1 + IC1) % M1;
ix2 = (IA2 * ix2 + IC2) % M2;
r[j] = (ix1 + ix2 * RM2) * RM1;
}
*idum = 1;
}
ix1 = (IA1 * ix1 + IC1) % M1;
ix2 = (IA2 * ix2 + IC2) % M2;
ix3 = (IA3 * ix3 + IC3) % M3;
j = 1 + ((97 * ix3) / M3);
if (j > 97 || j < 1) exit(1);
temp = r[j];
r[j] = (ix1 + ix2 * RM2) * RM1;
return (2.0 * temp - 1.0);
}
--
\__/ \__/ ***********************************************
(@@) (@@) * Frederic Vecoven - Researcher *
//||\\ //||\\ * Department of microelectronics *
* Institut Montefiore B28 - 4000 Liege *
\__/ \__/ \__/ * University of Liege - Belgium *
(oo) (oo) (oo) * Phone: (32)-41-662631 Fax: (32)-41-662950 *
//||\\ //||\\ //||\\ * *
* E-mail : vecoven@montefiore.ulg.ac.be *
FIGHTER CAPTURED ! * http://www.montefiore.ulg.ac.be/~vecoven/ *
***********************************************
---------------------------
>From richard@genome.wi.mit.edu (Richard Resnick)
Subject: Dlog code snippet request
Date: 30 Jan 1995 15:19:25 GMT
Organization: Whitehead Institute for Biomedical Research
Hello,
I've got a dialog box where I need an editable text item that accepts
strings bigger than 255 characters. GetDItem, followed by GetIText,
will snip off anything beyond the 255th character. Does anybody have a
snippet for how to handle this situation? I'm writing the interface in
pascal, so I'd appreciate Pascal code, but I'll take C if there's
nothing else.
Thanks in advance,
Richard
--
Richard Resnick Center for Genome Research
richard@genome.wi.mit.edu The Whitehead Institute, MIT
Keyboardist -- The Brad Paisley Trio
+++++++++++++++++++++++++++
>From rmah@panix.com (Robert Mah)
Date: Mon, 30 Jan 1995 23:15:46 -0500
Organization: One Step Beyond
[ crossposted to comp.sys.mac.programmer.help and alt.sources.mac with
followup's set to comp.sys.mac.programmer.help ]
richard@genome.wi.mit.edu (Richard Resnick) wrote:
)
) I've got a dialog box where I need an editable text item that accepts
) strings bigger than 255 characters. GetDItem, followed by GetIText,
) will snip off anything beyond the 255th character. Does anybody have a
) snippet for how to handle this situation?
Every edit text or static text item is represented by a handle to the
text it contains. So, just move the text you want into that handle.
The only caveat is that you have to check if you are modifying the
current edit text field. You may have to manually call DrawDialog()
after this, but I can't remember.
Try the following (sorry for the lack of comments, but I typed this
off the cuff)...
OSErr
SetDlogItemTextHdl( const DialogPtr dlog,
short item,
const Handle textHdl )
{
char hstate;
OSErr err;
Size textLen;
hstate = HGetState( textHdl );
HLock( textHdl );
textLen = GetHandleSize( textHdl );
err = SetDlogItemTextPtr( dlog, item, *textHdl, textLen );
HSetState( textHdl, hstate );
return err;
}
OSErr
SetDlogItemTextPtr( const DialogPtr dlog,
short item,
const char *textPtr,
Size textLen )
{
DialogPeek dpeek;
short itemType;
Rect itemBox;
Handle itemHdl;
TEHandle teHdl;
GetDialogItem( dlog, item, &itemType, &textHdl, &itemBox );
if( itemHdl == NULL )
return -1;
SetHandleSize( itemHdl, textLen );
if( (err = MemError()) != noErr )
return err;
BlockMoveData( textPtr, *itemHdl, textLen );
dpeek = (DialogPeek)dlog;
if( dpeek->editField == item - 1 ){
teHdl = dpeek->textH;
if( teHdl != NULL ){
TESetText( textPtr, textLen, teHdl );
TECalText( teHdl );
}
}
return noErr;
}
Cheers,
Rob
_______________________________________________________________________
Robert S. Mah Macintosh Software Development +1 212 947 6507
One Step Beyond and Network Consulting rmah@panix.com
+++++++++++++++++++++++++++
>From altworld@panix.com (Robert Schmunk)
Date: 31 Jan 1995 12:05:08 -0500
Organization: PANIX Public Access Internet and Unix, NYC
richard@genome.wi.mit.edu (Richard Resnick) wrote:
)
) I've got a dialog box where I need an editable text item that accepts
) strings bigger than 255 characters. GetDItem, followed by GetIText,
) will snip off anything beyond the 255th character. Does anybody have a
) snippet for how to handle this situation?
There is a sample code snippet called Modal Text Edit which handles
this located on the Apple Bookmark CDs that come with a "develop"
subscription. The snippet should also be available in the on-line
archives at ftp.apple.com somewhere in the dts directory.
rbs
--
Robert B. Schmunk
altworld@panix.com, pcrxs@nasagiss.giss.nasa.gov
http://barsoom.giss.nasa.gov/People/Schmunk.html
---------------------------
>From Lewis Gordon Pringle, Jr. <lewis@sophists.com>
Subject: FindWorkBreaks quirky?
Date: 26 Jan 1995 22:04:35 GMT
Organization: Sophist Solutions, Inc.
I'm using the TextUtils toolbox routine FindWordBreaks() in order to
word-wrap some text for a texteditor I'm writing. This routine seems to do
just what I need - and the documentation indicates that it is intended to
be used for such things as word-wrapping text.
However - it has one very disturbing anomoly. It seems to condider a space
character to be a word!
That is - if you operate on the text "We are good", and ask it to find the
word at position 2, it responds with a word found (2,3).
This would be awkward - but acceptable - if only the routine notified
me somehow which "words" were REALLY words - and which were simply strings
of spaces.
Now - I can use isspace() (from ctype.h) to tell if the word returned is a
REAL word - or one of these phony ones. This is what I am doing for now.
But doesn't this negate the usefulness of using this routine to begin with?
After all - it would then miss the case of - for example - a double-byte
Kanji space.
So - big picture - is this the right routine to be using to word-wrap text
in an internationally friendly manner? Assuming it is - then how do I use
it to achieve this?
Thanx,
Lewis.
- -----------------------------------------------------------------------------
Lewis Gordon Pringle, Jr. e-mail: <lewis@sophists.com>
Software Consultant phone: (508)-543-0041
Dogbert: "Always postpone meetings with time-wasting morons."
Dilbert: "How do you do that?"
Dogbert: "Can I get back to you on that?" -- Scott Adams
+++++++++++++++++++++++++++
>From paitech@hntp2.hinet.net (Pai Technology)
Date: 26 Jan 1995 23:39:24 GMT
Organization: HiNet
LewisGordonPringle wrote:
: That is - if you operate on the text "We are good", and ask it to find the
: word at position 2, it responds with a word found (2,3).
One of the 7 parameters of FindWordBreaks is "leadingEdge". It tells
FindWordBreaks whether you want to find the word before the offset or after
the offset. In this case, you have to pass false to leadingEdge.
: Now - I can use isspace() (from ctype.h) to tell if the word returned is a
: REAL word - or one of these phony ones. This is what I am doing for now.
: But doesn't this negate the usefulness of using this routine to begin with?
: After all - it would then miss the case of - for example - a double-byte
: Kanji space.
You can use the Script Manager routine CharacterType() to distinguish the
spaces.
Hao-yang Wang
Pai Technology, Inc.
Taipei
+++++++++++++++++++++++++++
>From presnick@qualcomm.com (Pete Resnick)
Date: Thu, 26 Jan 1995 18:02:15 -0600
Organization: QUALCOMM Incorporated
In article <3g969j$t3n@sundog.tiac.net>, Lewis Gordon Pringle, Jr.
<lewis@sophists.com> wrote:
> I'm using the TextUtils toolbox routine FindWordBreaks() in order to
>word-wrap some text for a texteditor I'm writing. This routine seems to do
>just what I need - and the documentation indicates that it is intended to
>be used for such things as word-wrapping text.
If you are using it to word-wrap text, you might consider calling
StyledLineBreak instead. It finds the appropriate place to break a line
for wrapping by calling PixelToChar and FindWordBreaks and then looking
for trailing spaces on the line.
> This would be awkward - but acceptable - if only the routine notified
>me somehow which "words" were REALLY words - and which were simply strings
>of spaces.
>
>Now - I can use isspace() (from ctype.h) to tell if the word returned is a
>REAL word - or one of these phony ones. This is what I am doing for now.
>But doesn't this negate the usefulness of using this routine to begin with?
>After all - it would then miss the case of - for example - a double-byte
>Kanji space.
Here's a routine that does this for you:
/* Check to see if the given text is all whitespace */
Boolean IsWhitespace(StringPtr theText, long textLen)
{
short theType;
/* Go through the characters of the text */
while(textLen > 0L) {
/* Get the character type for the current character */
theType = CharacterType((Ptr)theText++, 0, smCurrentScript);
/* If this is a two byte character, move through to the next byte */
if((theType & smcDoubleMask) != smChar1byte) {
++theText;
--textLen;
}
/* Check to see if it's whitespace */
theType &= (smcTypeMask | smcClassMask);
if(theType != (smCharPunct | smPunctBlank)) {
return false;
}
--textLen;
}
/* If it got this far, it was all whitespace */
return true;
}
Hope that helps.
--
Pete Resnick - presnick@qualcomm.com
QUALCOMM Incorporated
+++++++++++++++++++++++++++
>From Lewis Gordon Pringle, Jr. <lewis@sophists.com>
Date: 29 Jan 1995 04:47:01 GMT
Organization: Sophist Solutions, Inc.
In article <3g9brc$lmu@serv.hinet.net>, you write:
>From: paitech@hntp2.hinet.net (Pai Technology)
>Newsgroups: comp.sys.mac.programmer,comp.sys.mac.programmer.misc
>Subject: Re: FindWorkBreaks quirky?
...
>LewisGordonPringle wrote:
>: That is - if you operate on the text "We are good", and ask it to find the
>: word at position 2, it responds with a word found (2,3).
>
>One of the 7 parameters of FindWordBreaks is "leadingEdge". It tells
>FindWordBreaks whether you want to find the word before the offset or after
>the offset. In this case, you have to pass false to leadingEdge.
As far as I can tell - this is not relevant. The leadingEdge is equivilent to adding (or
not) one to the starting position of where you begin searching.
>: Now - I can use isspace() (from ctype.h) to tell if the word returned is a
>: REAL word - or one of these phony ones. This is what I am doing for now.
>: But doesn't this negate the usefulness of using this routine to begin with?
>: After all - it would then miss the case of - for example - a double-byte
>: Kanji space.
>
>You can use the Script Manager routine CharacterType() to distinguish the
>spaces.
Yes - thank you kindly. This is what I was really looking for.
Lewis.
- -----------------------------------------------------------------------------
Lewis Gordon Pringle, Jr. e-mail: <lewis@sophists.com>
Software Consultant phone: (508)-543-0041
Dogbert: "Always postpone meetings with time-wasting morons."
Dilbert: "How do you do that?"
Dogbert: "Can I get back to you on that?" -- Scott Adams
+++++++++++++++++++++++++++
>From Lewis Gordon Pringle, Jr. <lewis@sophists.com>
Date: 29 Jan 1995 04:53:39 GMT
Organization: Sophist Solutions, Inc.
In article <resnick-2601951802150001@resnick1.isdn.uiuc.edu> Pete Resnick, presnick@qualcomm.com
writes:
...
>In article <3g969j$t3n@sundog.tiac.net>, Lewis Gordon Pringle, Jr.
><lewis@sophists.com> wrote:
>
>> I'm using the TextUtils toolbox routine FindWordBreaks() in order to
>>word-wrap some text for a texteditor I'm writing. This routine seems to do
>>just what I need - and the documentation indicates that it is intended to
>>be used for such things as word-wrapping text.
>
>If you are using it to word-wrap text, you might consider calling
>StyledLineBreak instead. It finds the appropriate place to break a line
>for wrapping by calling PixelToChar and FindWordBreaks and then looking
>for trailing spaces on the line.
I'm doing more than just wrapping the text, and StyledLineBreak()
isn't sufficiently flexible for my needs - but thanx.
>> This would be awkward - but acceptable - if only the routine notified
>>me somehow which "words" were REALLY words - and which were simply strings
>>of spaces.
>>
>>Now - I can use isspace() (from ctype.h) to tell if the word returned is a
>>REAL word - or one of these phony ones. This is what I am doing for now.
>>But doesn't this negate the usefulness of using this routine to begin with?
>>After all - it would then miss the case of - for example - a double-byte
>>Kanji space.
>
>Here's a routine that does this for you:
>
..
> /* Get the character type for the current character */
> theType = CharacterType((Ptr)theText++, 0, smCurrentScript);
...
Again - thank you also. The CharacterType() functions is precisely
what I was looking for.
Lewis.
- -----------------------------------------------------------------------------
Lewis Gordon Pringle, Jr. e-mail: <lewis@sophists.com>
Software Consultant phone: (508)-543-0041
Dogbert: "Always postpone meetings with time-wasting morons."
Dilbert: "How do you do that?"
Dogbert: "Can I get back to you on that?" -- Scott Adams
+++++++++++++++++++++++++++
>From h+@metrowerks.com (Jon W{tte)
Date: Sun, 29 Jan 1995 18:27:12 +0100
Organization: The Conspiracy
In article <3g969j$t3n@sundog.tiac.net>,
Lewis Gordon Pringle, Jr. <lewis@sophists.com> wrote:
>However - it has one very disturbing anomoly. It seems to condider a space
>character to be a word!
Yes; series of punctuation is also considered to be a "word"
The easy solution is to just call CharacterType() and check for
the smIsPunct flag in the result on the first character; if
it's punctuation, call FindWordBreaks() again starting at the
end of the found range.
>Now - I can use isspace() (from ctype.h) to tell if the word returned is a
>REAL word - or one of these phony ones. This is what I am doing for now.
>But doesn't this negate the usefulness of using this routine to begin with?
>After all - it would then miss the case of - for example - a double-byte
>Kanji space.
Yes, never mix ANSI string/character functions with the real
text functions of the ToolBox. Use CharacterType() (formerly
known as CharType())
Cheers,
/ h+
--
Jon Wdtte (h+@metrowerks.com), Hagagatan 1, 113 48 Stockholm, Sweden
CFM 68k - Solutions to yesterdays problems, tomorrow!
+++++++++++++++++++++++++++
>From AppleGG@lamg.com (Gordon Apple)
Date: 01 Feb 1995 17:05:03 GMT
Organization: Los Angeles Macintosh Group BBS
I'm using the TextUtils toolbox routine FindWordBreaks() in order to
word-wrap some text for a texteditor I'm writing.*
So - big picture - is this the right routine to be using to word-wrap text
in an internationally friendly manner?
- ------------------
How about "StyledLineBreak"? That's what I am using. It seems to work
fairly well once you understand how to use it.
---------------------------
>From gneufeld@ccs.carleton.ca (Grant Neufeld)
Subject: Looking for Get-Put URL AE suite info
Date: Mon, 30 Jan 1995 20:27:29 GMT
Organization: Carleton Apple Research
I've been looking for the documentation on the Get and Put URL apple
events (used by many TCP apps), but have been unsuccessful. I searched
through umich, sumex-aim and a Peter N. Lewis mirror without luck. A
pointer would be appreciated. Thanks.
--
gneufeld@ccs.carleton.ca - http://arpp1.carleton.ca/Grant/ - Ottawa, Ontario
My views are too extreme to be those of anyone else. ki'hitwa'm kawa'pamitin
+++++++++++++++++++++++++++
>From scouten@metrowerks.com (Eric Scouten)
Date: Mon, 30 Jan 1995 16:34:35 -0600
Organization: metrowerks, inc.
In article <gneufeld-3001951527300001@192.0.1.2>, gneufeld@ccs.carleton.ca
(Grant Neufeld) wrote:
> I've been looking for the documentation on the Get and Put URL apple
> events (used by many TCP apps), but have been unsuccessful. I searched
> through umich, sumex-aim and a Peter N. Lewis mirror without luck. A
> pointer would be appreciated. Thanks.
Don't remember the exact URL, but you should look around on
ftp.acns.nwu.edu. John Norstad (author of NewsWatcher) took the lead on
designing this AE suite.
-es
__________________________________________________________________________
Eric Scouten Constructor Constructor
scouten@metrowerks.com Metrowerks, Inc.
Yea, and if It will be done, even in spite,
Then lend Thine hand to the masses,
Lest It be done incorrectly or woefully worse
By those not versed the the ways of the Dogcow.
- Memoirs of Clarus, the Dogcow
+++++++++++++++++++++++++++
>From gneufeld@ccs.carleton.ca (Grant Neufeld)
Date: Tue, 31 Jan 1995 02:35:57 GMT
Organization: Carleton Apple Research
scouten@metrowerks.com (Eric Scouten) wrote:
>
>Don't remember the exact URL, but you should look around on
>ftp.acns.nwu.edu.
Right you were:
ftp://ftp.acns.nwu.edu/pub/newswatcher/url-ae-standard.txt
--
gneufeld@ccs.carleton.ca - http://arpp1.carleton.ca/Grant/ - Ottawa, Ontario
My views are too extreme to be those of anyone else. ki'hitwa'm kawa'pamitin
---------------------------
>From mab@baretta.ideas.com (Aaron Barnett)
Subject: Random() replacement anyone?
Date: 26 Jan 1995 10:39:12 -0500
Organization: Ideas, Inc.
so has anyone come up with a better random function that they would like
to post? has anyone coded anything from a numerical recepies book?
--
firefly
+++++++++++++++++++++++++++
>From wilbaden@netcom.com (W.Baden)
Date: Sun, 29 Jan 1995 19:27:22 GMT
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
Aaron Barnett (mab@baretta.ideas.com) wrote:
: so has anyone come up with a better random function that they would like
: to post? has anyone coded anything from a numerical recepies book?
No discussion of random number generation would be complete without Donald
Knuth's recommendation. The enclosed listings untangle his routines from
_The Stanford Graphbase_, the so-called "Volume 3 1/2" of _The Art of
Computer Programming_.
D. E. Knuth, _The Stanford GraphBase_, Addison-Wesley, ISBN 0-201-54275-7
After you get the book, get the code for it. The book tells you how to ftp it.
The package handles all objections raised so far.
And it's fast.
In using these routines I've found the following renaming to be friendlier.
# define Random() gb_next_rand()
# define SetRandom(n) gb_init_rand(n)
# define GetRandom(n) gb_unif_rand(n)
Procedamus in pace. Wil wilbaden@netcom.com
==== gb_flip.h ====
# define gb_next_rand() (*gb_fptr >= 0 ? *gb_fptr-- : gb_flip_cycle())
# define mod_diff(x,y) (((x) - (y)) & 0x7FFFFFFF)
# define two_to_the_31 ((unsigned long) 0x80000000)
extern long *gb_fptr;
extern long gb_flip_cycle(void);
extern void gb_init_rand(long seed);
extern long gb_unif_rand(long m);
extern int gb_flip(void);
==== gb_flip.c ====
/*
* gb_flip
* D. E. Knuth, _The Stanford GraphBase_, Addison-Wesley, ISBN 0-201-54275-7
*/
# include <stdio.h>
# include "gb_flip.h"
/* Private Declarations */
static long A[56] = {-1};
/* External Declarations */
long *gb_fptr = A;
# define gb_next_rand() (*gb_fptr >= 0 ? *gb_fptr-- : gb_flip_cycle())
/* External Functions */
long gb_flip_cycle(void)
{
register long *ii, *jj;
for (ii = &A[1], jj = &A[32]; jj <= &A[55]; ii++, jj++)
*ii = mod_diff(*ii, *jj);
for (jj = &A[1]; ii<= &A[55]; ii++, jj++)
*ii = mod_diff(*ii, *jj);
gb_fptr = &A[54];
return A[55];
}
void gb_init_rand(long seed)
{
register long i;
register long prev = seed, next = 1;
seed = prev = mod_diff(prev, 0);
A[55] = prev;
for (i = 21; i; i =(i + 21) % 55) {
A[i] = next;
/* Compute a new next value. */
next = mod_diff(prev, next);
if (seed & 1)
seed = 0x40000000 + (seed >> 1);
else
seed >>= 1;
next = mod_diff(next, seed);
prev = A[i];
}
/* Get the array values ``warmed up''. */
(void) gb_flip_cycle();
(void) gb_flip_cycle();
(void) gb_flip_cycle();
(void) gb_flip_cycle();
(void) gb_flip_cycle();
}
long gb_unif_rand(long m)
{
register unsigned long t = two_to_the_31 - (two_to_the_31 % m);
register long r;
do {
r = gb_next_rand();
} while (t <= (unsigned long) r);
return r % m;
}
int gb_flip(void)
{
int j;
gb_init_rand(-314159L);
if (gb_next_rand() != 119318998) {
fprintf(stderr,"Failure on the first try.\n");
return -1;
}
for (j = 1; j <= 133; j++) gb_next_rand();
if (gb_unif_rand(0x55555555L) != 748103812) {
fprintf(stderr,"Failure on the second try.\n");
return -2;
}
/* fprintf(stderr,"OK, the gb_flip_routines seem to work.\n"); */
return 0;
}
---------------------------
>From cwong@qualcomm.com (Clarence Wong)
Subject: UnloadSeg - unloading code segments
Date: Tue, 24 Jan 1995 14:35:07 -0800
Organization: Qualcomm
The Segment Manager chapter in New Inside Mac: Processes says:
You can call UnloadSeg at any time except when you are executing code
contained in the segment to be unloaded. A typical strategy is to unload
all code segments except segment 1 and any other essential code segments
each time through your applicationUs main event loop.
So, say you have the following code in main.c:
void unloadSegments ()
{
UnloadSeg ((void *) someFunctionInSeg2);
UnloadSeg ((void *) anotherFunctionInSeg3);
}
void eventLoop ()
{
EventRecord theEvent;
OSErr theError;
long sleepTime;
Boolean gotAnEvent;
while (!gQuitting) {
theError = noErr;
sleepTime = gPeriodicTask ? 1 : GetDblTime ();
if (gInBackground)
sleepTime = 120L;
gotAnEvent = WaitNextEvent (everyEvent, &theEvent, sleepTime,
gCursorRgn);
if (gotAnEvent)
theError = doEvent (&theEvent);
if (!theError)
theError = doPeriodicTask ();
if (theError)
reportAnError (theError);
unloadSegments ();
}
}
What happens if there isn't enough memory to load a segment into memory? I
get a system error 15 (segment loader error). Do I need to patch
_LoadSegment to check for enough memory? Even if I do, the Segment Manager
automatically calls LoadSegment; how do I return this error to my main
eventloop? I've seen some code where all the code resources are loaded,
made unpurgeable and locked at initialization. That makes sense for smaller
applications, but for larger applications, Inside Mac's advice looks
better. Are they not telling the whole story or is there something I've
missed? Scott Knaster's book says the same thing.
+++++++++++++++++++++++++++
>From crawford@scipp.ucsc.edu (Mike Crawford)
Date: 25 Jan 1995 01:14:37 GMT
Organization: Santa Cruz Institute for Particle Physics
Regarding the problem of running out of memory when loading a segment...
There are various options:
1. Crash. A frequently used solution
2. Make the crashes rare by setting the application partition to an amount
that seems safe based on your testing. Probably the most popular.
3. Test that there is enough memory available before making any intersegment
call. Most reliably, but no one does this. One could do this by using
GetResource( 'CODE', kWhatever) and checking that the returned handle is
not nil.
4. Do #3, but only do at at times when you think you're likely to be out of
memory.
5. Once through the main event loop, check the available memory, and if it
is less than a certain amount, advise the user to close some windows.
6. Probably the most practical, semireliable solution; allocate a block which
is bigger than any of your segments (bigger than 32K). Maybe as big as
several segments. Use the grow zone proc you can pass into SetGrowZone. If
your proc is called, free the block you have stashed, and set a flag that is
checked during the main event loop. If you see the flag set, advise the user
to save and quit.
Of course, if you can't load the segment because a server went down, or you
broke the network cable, well, you're out of luck.
--
Mike Crawford
crawford@scruznet.com <-- note change of address.
crawford@maxwell.ucsc.edu <-- Finger Me here for PGP Public Key
+++++++++++++++++++++++++++
>From cwong@qualcomm.com (Clarence Wong)
Date: Wed, 25 Jan 1995 13:29:19 -0800
Organization: Qualcomm
In article <3g48lt$1mq@darkstar.UCSC.EDU>, crawford@scipp.ucsc.edu (Mike
Crawford) wrote:
> Regarding the problem of running out of memory when loading a segment...
>
> There are various options:
>
> 1. Crash. A frequently used solution
>
> 2. Make the crashes rare by setting the application partition to an amount
> that seems safe based on your testing. Probably the most popular.
>
> 3. Test that there is enough memory available before making any intersegment
> call. Most reliably, but no one does this. One could do this by using
> GetResource( 'CODE', kWhatever) and checking that the returned handle is
> not nil.
>
> 4. Do #3, but only do at at times when you think you're likely to be out of
> memory.
>
> 5. Once through the main event loop, check the available memory, and if it
> is less than a certain amount, advise the user to close some windows.
>
> 6. Probably the most practical, semireliable solution; allocate a block which
> is bigger than any of your segments (bigger than 32K). Maybe as big as
> several segments. Use the grow zone proc you can pass into SetGrowZone. If
> your proc is called, free the block you have stashed, and set a flag that is
> checked during the main event loop. If you see the flag set, advise the user
> to save and quit.
>
Thanks for the response. I think I did miss something important in NIM:
Memory. I was doing option 1,2, 5 and 6 and was thinking about doing option
3. The problem with checking if there is enough memory before calling any
intersegment call is that it is a real pain-- this is why no one does this.
Instead, Inside Mac recommends maintaining a memory cushion and checking if
there is enough memory for any dynamic memory allocation (NewPtr and
NewHandle calls) you do. Basically, you write wrapper functions for the two
calls that check memory before they allocate. If memory request <
(available memory + memory cushion) then the request is granted. The
growzone is temporarily set to nil so that emergency memory isn't purged.
The problem I was experiencing was that memory was being hogged by my
dynamic memory calls while the segment loader starved.
-Clarence
+++++++++++++++++++++++++++
>From cwong@qualcomm.com (Clarence Wong)
Date: Wed, 25 Jan 1995 13:58:12 -0800
Organization: Qualcomm
In article <cwong-250195132919@cwong.qualcomm.com>, cwong@qualcomm.com
(Clarence Wong) wrote:
> In article <3g48lt$1mq@darkstar.UCSC.EDU>, crawford@scipp.ucsc.edu (Mike
> Crawford) wrote:
>
> > Regarding the problem of running out of memory when loading a segment...
> >
> > There are various options:
> >
> > 1. Crash. A frequently used solution
> >
> > 2. Make the crashes rare by setting the application partition to an amount
> > that seems safe based on your testing. Probably the most popular.
> >
> > 3. Test that there is enough memory available before making any intersegment
> > call. Most reliably, but no one does this. One could do this by using
> > GetResource( 'CODE', kWhatever) and checking that the returned handle is
> > not nil.
> >
> > 4. Do #3, but only do at at times when you think you're likely to be out of
> > memory.
> >
> > 5. Once through the main event loop, check the available memory, and if it
> > is less than a certain amount, advise the user to close some windows.
> >
> > 6. Probably the most practical, semireliable solution; allocate a block which
> > is bigger than any of your segments (bigger than 32K). Maybe as big as
> > several segments. Use the grow zone proc you can pass into SetGrowZone. If
> > your proc is called, free the block you have stashed, and set a flag that is
> > checked during the main event loop. If you see the flag set, advise the user
> > to save and quit.
> >
>
> Thanks for the response. I think I did miss something important in NIM:
> Memory. I was doing option 1,2, 5 and 6 and was thinking about doing option
> 3. The problem with checking if there is enough memory before calling any
> intersegment call is that it is a real pain-- this is why no one does this.
>
> Instead, Inside Mac recommends maintaining a memory cushion and checking if
> there is enough memory for any dynamic memory allocation (NewPtr and
> NewHandle calls) you do. Basically, you write wrapper functions for the two
> calls that check memory before they allocate. If memory request <
> (available memory + memory cushion) then the request is granted. The
> growzone is temporarily set to nil so that emergency memory isn't purged.
> The problem I was experiencing was that memory was being hogged by my
> dynamic memory calls while the segment loader starved.
>
> -Clarence
Oooops. Should read: If memory request < (available memory - memory
cushion) then the request is granted.
+++++++++++++++++++++++++++
>From gurgle@dnai.com (Pete Gontier)
Date: Thu, 26 Jan 1995 18:15:58 -0700
Organization: cellular
In article <3g48lt$1mq@darkstar.UCSC.EDU>,
crawford@scipp.ucsc.edu (Mike Crawford) wrote:
> Regarding the problem of running out of memory when loading a segment...
> There are various options:
You forgot:
7. Don't load segments.
Have CodeWarrior or MPW make all your segments go away by linking all your
code into a single resource. Alternately, or if you are using a Symantec
product, mark all your segments pre-load and locked.
Of course, this is not a solution for someone who actually wants to unload
segments, but most often what people want is to make System Error 15 go
away, and they don't much care how they do it.
______________________________________________________________________________
Pete Gontier -- MacZealotry, Ink. -- gurgle@dnai.com
"It's great to work for a company that lets you build good software
and doesn't give you any shit..."
-- John McEnerney, Metrowerks PowerPC Product Architect
+++++++++++++++++++++++++++
>From rickgenter@aol.com (RickGenter)
Date: 31 Jan 1995 08:20:48 -0500
Organization: America Online, Inc. (1-800-827-6364)
>>>
You forgot:
7. Don't load segments.
Have CodeWarrior or MPW make all your segments go away by linking all your
code into a single resource. Alternately, or if you are using a Symantec
product, mark all your segments pre-load and locked.
<<<
The problem I have with this solution is that it tends to lead to code
bloat. I may have a lot of code in my application that is rarely executed.
(For example, look at most of Microsoft Word/Excel/etc.) Through the
judicious use of segments, I can make my application have a *much* smaller
memory footprint than it would have otherwise.
Rick Genter
+++++++++++++++++++++++++++
>From jens_alfke@powertalk.apple.com (Jens Alfke)
Date: Thu, 26 Jan 1995 22:27:45 GMT
Organization: Apple Computer, Inc.
In article <cwong-250195132919@cwong.qualcomm.com>, cwong@qualcomm.com
(Clarence Wong) wrote:
> Instead, Inside Mac recommends maintaining a memory cushion and checking if
> there is enough memory for any dynamic memory allocation (NewPtr and
> NewHandle calls) you do. Basically, you write wrapper functions for the two
> calls that check memory before they allocate. If memory request <
> (available memory + memory cushion) then the request is granted. The
> growzone is temporarily set to nil so that emergency memory isn't purged.
This will work, but I find it much easier (and faster) to leave the GZProc
in place and let it tell me when there's not enough memory. E.g:
Handle MyNewHandle( Size s )
{
gCanEatCushion = false;
Handle h = NewHandle(s);
gCanEatCushion = true;
if( !h )
THROW( MemError() );
}
gCanEatCushion is checked in the GZproc; if it's false, it will not
release the cushion. This means that the app's memory allocations will not
eat into the cushion space, but memory allocated by other things (such as
the Toolbox) can.
Jens Alfke_________OpenDoc Geometer_________jens_alfke@powertalk.apple.com
OpenDoc info: FTP to cil.org
Visit Scenic Flood Control Dam No. 3.
+++++++++++++++++++++++++++
>From jens_alfke@powertalk.apple.com (Jens Alfke)
Date: Thu, 26 Jan 1995 22:30:15 GMT
Organization: Apple Computer, Inc.
> In article <3g48lt$1mq@darkstar.UCSC.EDU>, crawford@scipp.ucsc.edu (Mike
> Crawford) wrote:
>
> > Regarding the problem of running out of memory when loading a segment...
> >
> > There are various options:
You didn't mention the option of patching _LoadSeg, which is taken by
MacApp and the Finder; I believe both create a subheap especially for code
segments, which makes it easier to assure that a segment can always be
loaded.
Metrowerks' 68k runtime environment also patches _LoadSeg for other
reasons, but unfortunately they don't allow the programmer to hook into it
to do things like this.
Jens Alfke_________OpenDoc Geometer_________jens_alfke@powertalk.apple.com
OpenDoc info: FTP to cil.org
Visit Scenic Flood Control Dam No. 3.
+++++++++++++++++++++++++++
>From rmah@panix.com (Robert Mah)
Date: Wed, 01 Feb 1995 17:36:48 -0500
Organization: One Step Beyond
jens_alfke@powertalk.apple.com (Jens Alfke) wrote:
) Metrowerks' 68k runtime environment also patches _LoadSeg for other
) reasons, but unfortunately they don't allow the programmer to hook
) into it to do things like this.
I believe this patch has been removed in CW-5 because of lot's of user
complaints (mine among them).
Cheers,
Rob
_______________________________________________________________________
Robert S. Mah Macintosh Software Development +1 212 947 6507
One Step Beyond and Network Consulting rmah@panix.com
---------------------------
>From bb@lightside.com (Bob Bradley)
Subject: Where to send applications I've written?
Date: 1 Feb 1995 07:46:30 GMT
Organization: SPC
Where would I send software I've written to get distributed to the major
FTP sites (and possibly commerical sites)? I remember there being
somewhere to send mail (MacGifts?) but, I don't know the exact e-mail
address. I wrote something (freeware) that I'd like to get out but, can't
find the address, and I couldn't find anything in the CSMP FAQ. I'd
appreciate any info.
Thanks
+++++++++++++++++++++++++++
>From Matt Slot <fprefect@engin.umich.edu>
Date: 1 Feb 1995 08:34:40 GMT
Organization: University of Michigan
Try mailing your binhexes (with appropriate titles/headers) to:
macgifts@sumex-aim.stanford.edu
This hits Sumex, MacArchives, mirrors, and assorted sites along
the way. Its the best way to hit a large Internet audience with
one mailing.
Matt
---------------------------
End of C.S.M.P. Digest
**********************